package com.ssy.lingxi.purchase.serviceimpl.tender;

import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.message.api.constant.MessageTemplateCode;
import com.ssy.lingxi.message.api.feign.SystemMessageControllerFeign;
import com.ssy.lingxi.message.api.vo.request.SystemMessageRequest;
import com.ssy.lingxi.purchase.api.dto.request.tender.ExpertExtractQueryRequest;
import com.ssy.lingxi.purchase.api.dto.request.tender.SimpleIdRequest;
import com.ssy.lingxi.purchase.api.enums.tender.ExpertExtractStatusEnum;
import com.ssy.lingxi.purchase.api.enums.tender.TenderStatusEnum;
import com.ssy.lingxi.purchase.entity.tender.*;
import com.ssy.lingxi.purchase.repository.tender.*;
import com.ssy.lingxi.purchase.service.tender.IExpertExtractService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 评标专家库实现类
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/6/22
 */
@Service
public class ExpertExtractServiceImpl implements IExpertExtractService {

    @Resource
    private ExpertExtractRepository expertExtractRepository;

    @Resource
    private ExpertExtractRecordRepository expertExtractRecordRepository;

    @Resource
    private InviteTenderRepository inviteTenderRepository;

    @Resource
    private ExpertRepository expertRepository;

    @Resource
    private InviteTenderInCheckRecordRepository inviteTenderInCheckRecordRepository;

    @Resource
    private SystemMessageControllerFeign systemMessageControllerFeign;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 查询评标专家库列表
     * @param pageVO 分页实体
     * @param expertExtractQueryRequest 评标专家库
     * @return
     */
    @Override
    public Page<ExpertExtract> getExpertExtractList(UserLoginCacheDTO sysUser, PageVO pageVO, ExpertExtractQueryRequest expertExtractQueryRequest){
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize());
        return expertExtractRepository.findAll(getSpecification(sysUser, expertExtractQueryRequest), page);
    }

    /**
     * 查询评标专家库
     * @return id
     */
    @Override
    public ExpertExtract getExpertExtract(UserLoginCacheDTO sysUser, Long id){
        return expertExtractRepository.findById(id).orElse(null);
    }

    /**
     * 添加/修改评标专家抽取
     * @param expertExtract
     * @return
     */
    @Transactional
    @Override
    public String saveOrUpdateExpertExtract(UserLoginCacheDTO sysUser, ExpertExtract expertExtract){
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        Long userId = sysUser.getUserId();
        List<ExpertExtractRecord> expertExtractRecordList = expertExtract.getExpertExtractRecordList();
        InviteTender inviteTenderRequest = expertExtract.getInviteTender();
        //判断招标记录是否存在
        if(inviteTenderRequest != null){
            Long inviteTenderId = inviteTenderRequest.getId();
            InviteTender inviteTender = inviteTenderRepository.findById(inviteTenderId).orElse(null);
            if(inviteTender == null){
                throw new BusinessException(ResponseCode.PURCHASE_INVITE_TENDER_NOT_EXIST);
            }
            expertExtract.setInviteTender(inviteTender);
        }else{
            throw new BusinessException(ResponseCode.PURCHASE_INVITE_TENDER_NOT_EXIST);
        }
        //判断名称是否重复
        Long id = expertExtract.getId();
        if(id != null && id > 0){
            ExpertExtract currentExpertExtract = expertExtractRepository.findById(id).orElse(null);
            if(currentExpertExtract == null){
                throw new BusinessException(ResponseCode.PURCHASE_TENDER_EXPERT_NOT_EXIST);
            }
            currentExpertExtract.setName(expertExtract.getName());

            //修改之前数据库的抽取记录
            List<Long> expertExtractRecordIdList = new ArrayList<>();
            List<ExpertExtractRecord> currentExpertExtractRecordList = currentExpertExtract.getExpertExtractRecordList();
            if(currentExpertExtractRecordList != null && currentExpertExtractRecordList.size() > 0){
                expertExtractRecordIdList = currentExpertExtractRecordList.stream().map(ExpertExtractRecord::getId).collect(Collectors.toList());
            }
            List<Long> finalExpertExtractRecordIdList = expertExtractRecordIdList;
            List<ExpertExtractRecord> newExpertExtractRecordList = expertExtractRecordList.stream().map(expertExtractRecord -> {
                Long expertExtractRecordId = expertExtractRecord.getId();
                if(finalExpertExtractRecordIdList.size() > 0){
                    finalExpertExtractRecordIdList.remove(expertExtractRecordId);
                }

                Long expertId = expertExtractRecord.getExpert().getId();
                if(expertId != null && expertId > 0){
                    Expert expert = expertRepository.findById(expertId).orElse(null);
                    if(expert != null){
                        expertExtractRecord.setExpert(expert);
                        expertExtractRecord.setExpertExtract(currentExpertExtract);
                        return expertExtractRecord;
                    }
                }
                return null;
            }).filter(Objects::nonNull).collect(Collectors.toList());
            currentExpertExtract.setExpertExtractRecordList(newExpertExtractRecordList);

            List<ExpertExtractQuery> expertExtractQueryList = expertExtract.getExpertExtractQueryList();
            expertExtractQueryList.forEach(expertExtractQuery -> expertExtractQuery.setExpertExtract(currentExpertExtract));

            //数据库持久化对象
            expertExtractRepository.saveAndFlush(currentExpertExtract);

            //删除旧数据
            if(finalExpertExtractRecordIdList.size() > 0){
                expertExtractRecordRepository.deleteByIdIn(finalExpertExtractRecordIdList);
            }

        }else{
            expertExtract.setMemberId(memberId);
            expertExtract.setMemberName(sysUser.getCompany());
            expertExtract.setMemberRoleId(memberRoleId);
            expertExtract.setMemberRoleName(sysUser.getMemberRoleName());
            expertExtract.setUserId(userId);
            expertExtract.setUserName(sysUser.getUserName());
            expertExtract.setCreateTime(System.currentTimeMillis());

            List<ExpertExtractRecord> newExpertExtractRecordList = expertExtractRecordList.stream().map(expertExtractRecord -> {
                Long expertId = expertExtractRecord.getExpert().getId();
                if(expertId != null && expertId > 0){
                    Expert expert = expertRepository.findById(expertId).orElse(null);
                    if(expert != null){
                        expertExtractRecord.setExpert(expert);
                        expertExtractRecord.setExpertExtract(expertExtract);
                        return expertExtractRecord;
                    }
                }
                return null;
            }).filter(Objects::nonNull).collect(Collectors.toList());
            expertExtract.setExpertExtractRecordList(newExpertExtractRecordList);

            List<ExpertExtractQuery> expertExtractQueryList = expertExtract.getExpertExtractQueryList();
            expertExtractQueryList.forEach(expertExtractQuery -> {
                expertExtractQuery.setExpertExtract(expertExtract);
            });
            //数据库持久化对象
            expertExtractRepository.saveAndFlush(expertExtract);

            InviteTender inviteTender = expertExtract.getInviteTender();
            inviteTender.setIsExistExpertExtract(true);
            inviteTenderRepository.saveAndFlush(inviteTender);
        }
        return ResponseCode.SUCCESS.getMessage();
    }

    /**
     * 发送抽取通知
     * @param sysUser
     * @param simpleIdRequest
     * @return
     */
    @Override
    public Boolean sendExpertExtract(UserLoginCacheDTO sysUser, SimpleIdRequest simpleIdRequest) {
        Long id = simpleIdRequest.getId();
        if(id != null && id > 0){
            ExpertExtract expertExtract = expertExtractRepository.findById(id).orElse(null);
            if(expertExtract != null){
                List<SystemMessageRequest> systemMessageRequestList = new ArrayList<>();
                InviteTender inviteTender = expertExtract.getInviteTender();
                List<ExpertExtractRecord> expertExtractRecordList = expertExtract.getExpertExtractRecordList();
                expertExtractRecordList.forEach(expertExtractRecord -> {
                    expertExtractRecord.setStatus(ExpertExtractStatusEnum.Send.getCode());

                    Expert expert = expertExtractRecord.getExpert();
                    //发送消息
                    SystemMessageRequest systemMessageRequest = new SystemMessageRequest();
                    systemMessageRequest.setMemberId(expert.getMemberId());
                    systemMessageRequest.setRoleId(expert.getMemberRoleId());
                    systemMessageRequest.setUserId(expert.getExpertUserId());
                    systemMessageRequest.setMessageNotice(MessageTemplateCode.bidding_expert_evaluate);
                    List<String> params = new ArrayList<>();
                    params.add(inviteTender.getCode());
                    params.add(inviteTender.getProjectName());
                    systemMessageRequest.setParams(params);
                    systemMessageRequestList.add(systemMessageRequest);
                });
                expertExtract.setStatus(true);
                expertExtract.setExpertExtractRecordList(expertExtractRecordList);
                expertExtractRepository.saveAndFlush(expertExtract);

                try {
                    //发送消息
                    systemMessageControllerFeign.batchSendSystemMessage(systemMessageRequestList);
                }catch (Exception e){
                    e.printStackTrace();
                }

                //招标内部状态
                InviteTenderInCheckRecord inviteTenderInCheckRecord = new InviteTenderInCheckRecord();
                inviteTenderInCheckRecord.setStatusValue(TenderStatusEnum.HAS_SEND_EVALUATION_NOTICE.getMessage());
                inviteTenderInCheckRecord.setOperationValue(TenderStatusEnum.SEND_EVALUATION_NOTICE.getMessage());
                inviteTenderInCheckRecord.setUserId(sysUser.getUserId());
                inviteTenderInCheckRecord.setUserName(sysUser.getUserName());
                inviteTenderInCheckRecord.setUserJobTitle(sysUser.getUserJobTitle());
                inviteTenderInCheckRecord.setUserOrgName(sysUser.getUserOrgName());
                inviteTenderInCheckRecord.setMemberId(sysUser.getMemberId());
                inviteTenderInCheckRecord.setMemberName(sysUser.getCompany());
                inviteTenderInCheckRecord.setMemberRoleId(sysUser.getMemberRoleId());
                inviteTenderInCheckRecord.setMemberRoleName(sysUser.getMemberRoleName());
                inviteTenderInCheckRecord.setCreateTime(System.currentTimeMillis());
                inviteTenderInCheckRecord.setInviteTenderId(expertExtract.getInviteTender().getId());
                inviteTenderInCheckRecordRepository.saveAndFlush(inviteTenderInCheckRecord);

                return true;
            }
        }
        throw new BusinessException(ResponseCode.PURCHASE_EXPERT_EXTRACT_NOT_EXIST);
    }

    /**
     * 再次发送抽取通知
     * @param sysUser
     * @param simpleIdRequest
     * @return
     */
    @Override
    public Boolean sendExpertExtractAgain(UserLoginCacheDTO sysUser, SimpleIdRequest simpleIdRequest) {
        Long id = simpleIdRequest.getId();
        if(id != null && id > 0){
            ExpertExtract expertExtract = expertExtractRepository.findById(id).orElse(null);
            if(expertExtract != null){
                List<SystemMessageRequest> systemMessageRequestList = new ArrayList<>();
                InviteTender inviteTender = expertExtract.getInviteTender();
                List<ExpertExtractRecord> expertExtractRecordList = expertExtract.getExpertExtractRecordList();
                expertExtractRecordList.forEach(expertExtractRecord -> {
                    Integer status = expertExtractRecord.getStatus();
                    if(ExpertExtractStatusEnum.Send.getCode().equals(status)){
                        Expert expert = expertExtractRecord.getExpert();
                        //发送消息
                        SystemMessageRequest systemMessageRequest = new SystemMessageRequest();
                        systemMessageRequest.setMemberId(expert.getMemberId());
                        systemMessageRequest.setRoleId(expert.getMemberRoleId());
                        systemMessageRequest.setUserId(expert.getExpertUserId());
                        systemMessageRequest.setMessageNotice(MessageTemplateCode.bidding_expert_evaluate);
                        List<String> params = new ArrayList<>();
                        params.add(inviteTender.getCode());
                        params.add(inviteTender.getProjectName());
                        systemMessageRequest.setParams(params);
                        systemMessageRequestList.add(systemMessageRequest);
                    }
                });
                //发送消息
                systemMessageControllerFeign.batchSendSystemMessage(systemMessageRequestList);

                //招标内部状态
                InviteTenderInCheckRecord inviteTenderInCheckRecord = new InviteTenderInCheckRecord();
                inviteTenderInCheckRecord.setStatusValue(TenderStatusEnum.HAS_SEND_EVALUATION_NOTICE.getMessage());
                inviteTenderInCheckRecord.setOperationValue(TenderStatusEnum.AGAIN_SEND_EVALUATION_NOTICE.getMessage());
                inviteTenderInCheckRecord.setUserId(sysUser.getUserId());
                inviteTenderInCheckRecord.setUserName(sysUser.getUserName());
                inviteTenderInCheckRecord.setUserJobTitle(sysUser.getUserJobTitle());
                inviteTenderInCheckRecord.setUserOrgName(sysUser.getUserOrgName());
                inviteTenderInCheckRecord.setMemberId(sysUser.getMemberId());
                inviteTenderInCheckRecord.setMemberName(sysUser.getCompany());
                inviteTenderInCheckRecord.setMemberRoleId(sysUser.getMemberRoleId());
                inviteTenderInCheckRecord.setMemberRoleName(sysUser.getMemberRoleName());
                inviteTenderInCheckRecord.setCreateTime(System.currentTimeMillis());
                inviteTenderInCheckRecord.setInviteTenderId(expertExtract.getInviteTender().getId());
                inviteTenderInCheckRecordRepository.saveAndFlush(inviteTenderInCheckRecord);

                return true;
            }
        }
        throw new BusinessException(ResponseCode.PURCHASE_EXPERT_EXTRACT_NOT_EXIST);
    }

    /**
     * 删除
     * @param sysUser
     * @param simpleIdRequest
     * @return
     */
    @Override
    public Boolean deleteExpertExtract(UserLoginCacheDTO sysUser, SimpleIdRequest simpleIdRequest) {
        Long id = simpleIdRequest.getId();
        if(id != null && id > 0){
            ExpertExtract expertExtract = expertExtractRepository.findById(id).orElse(null);
            if(expertExtract != null){
                Boolean status = expertExtract.getStatus();
                if(!status){
                    expertExtractRepository.delete(expertExtract);
                    return true;
                }else{
                    throw new BusinessException(ResponseCode.PURCHASE_EXPERT_EXTRACT_STATUS_NOT_DELETE);
                }
            }
        }
        throw new BusinessException(ResponseCode.PURCHASE_EXPERT_EXTRACT_NOT_EXIST);
    }

    /**
     * 构建查询条件
     * @param sysUser
     * @return
     */
    private Specification<ExpertExtract> getSpecification(UserLoginCacheDTO sysUser, ExpertExtractQueryRequest expertExtractQueryRequest){
        return new Specification<ExpertExtract>() {
            @Override
            public Predicate toPredicate(Root<ExpertExtract> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Predicate finalConditions = criteriaBuilder.conjunction();

                String name = expertExtractQueryRequest.getName();
                String inviteTenderCode = expertExtractQueryRequest.getInviteTenderCode();

                if(!StringUtils.isEmpty(name)){
                    finalConditions = criteriaBuilder.and(finalConditions, criteriaBuilder.like(root.get("name").as(String.class), "%" + name + "%"));
                }
                if(!StringUtils.isEmpty(inviteTenderCode)){
                    finalConditions = criteriaBuilder.and(finalConditions, criteriaBuilder.like(root.get("inviteTender").get("code").as(String.class), "%" + inviteTenderCode + "%"));
                }
                if(sysUser.getMemberId() != null && sysUser.getMemberId() > 0){
                    finalConditions = criteriaBuilder.and(finalConditions, criteriaBuilder.equal(root.get("memberId").as(Long.class), sysUser.getMemberId()));
                }
                if(sysUser.getMemberRoleId() != null && sysUser.getMemberRoleId() > 0){
                    finalConditions = criteriaBuilder.and(finalConditions, criteriaBuilder.equal(root.get("memberRoleId").as(Long.class), sysUser.getMemberRoleId()));
                }
                query.orderBy(criteriaBuilder.desc(root.get("id")));
                return finalConditions;
            }
        };
    }
}

